#include "../include/thread_pool.h"
#include <bits/pthreadtypes.h>

// 每个子线程在执行的函数执行体
void *threadFunc(void *arg){
    // 不断地从任务队列中获取任务，并执行
    threadpool_t *pThreadpool = (threadpool_t *)arg;
    while(1){
        task_t *ptask = (task_t *)calloc(1,sizeof(task_t));
        taskDeque(&pThreadpool->que,&ptask);
        if(ptask){
            // 执行业务逻辑
            doTask(ptask);
            free(ptask); // 执行完任务释放节点
        }else{
            break; // ptask为NULL的情况
        }
    }
    printf("thread %ld is exiting.\n",pthread_self());
    return NULL;
}

// 线程池初始化
int threadpoolInit(threadpool_t *pThreadpool, int num){
    pThreadpool->pthreadNum = num;
    pThreadpool->pthreads = (pthread_t *)calloc(num,sizeof(pthread_t));
    queueInit(&pThreadpool->que);

    return 0;
}

// 销毁线程池
int threadpoolDestroy(threadpool_t *pthreadpool){
    free(pthreadpool->pthreads);
    queueDestroy(&pthreadpool->que);

    return 0;
}

// 启动线程池
int threadpoolStart(threadpool_t *pthreadpool){
    if(pthreadpool){
        for(int i = 0; i < pthreadpool->pthreadNum; ++i){
            int ret = pthread_create(&pthreadpool->pthreads[i],NULL,threadFunc,pthreadpool);
            THREAD_ERROR_CHECK(ret,"pthread_create");
        }
    }
    return 0;
}

int threadpoolStop(threadpool_t *pthreadpool){
    // 如果任务队列中还有任务，先等待一下，所有任务执行完成之后，再发广播，退出
    while(!queueIsEmpty(&pthreadpool->que)){
        sleep(1);
    }

    // 发广播，通知所有的子线程退出
    broadcastALL(&pthreadpool->que);
    // 回收所有子线程的资源
    for(int i = 0; i < pthreadpool->pthreadNum; ++i){
        pthread_join(pthreadpool->pthreads[i],NULL);
    }
    return 0;
}
